package com.gitee.deeround.jdbchelper.resultSetExtractors;

import com.gitee.deeround.jdbchelper.exception.DbException;
import com.gitee.deeround.jdbchelper.out.DataType;

import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class BaseResultSetExtractor {
    /**
     * 字段名转成小写
     */
    protected String resolveColumnName(String columnName) {
        return columnName.toLowerCase();
    }

    /**
     * 字段数据类型转自定义数据类型
     */
    protected DataType resolveDataType(int dataType) {
        //java.sql.Types
        Map<Integer, DataType> typeMap = new HashMap<>();
        typeMap.put(Types.BIT, DataType.Integer);
        typeMap.put(Types.TINYINT, DataType.Integer);
        typeMap.put(Types.SMALLINT, DataType.Integer);
        typeMap.put(Types.INTEGER, DataType.Integer);
        typeMap.put(Types.BIGINT, DataType.Integer);

        typeMap.put(Types.FLOAT, DataType.Decimal);
        typeMap.put(Types.REAL, DataType.Decimal);
        typeMap.put(Types.DOUBLE, DataType.Decimal);
        typeMap.put(Types.NUMERIC, DataType.Decimal);
        typeMap.put(Types.DECIMAL, DataType.Decimal);

        typeMap.put(Types.CHAR, DataType.String);
        typeMap.put(Types.VARCHAR, DataType.String);
        typeMap.put(Types.LONGVARCHAR, DataType.String);

        typeMap.put(Types.DATE, DataType.Date);
        typeMap.put(Types.TIME, DataType.Date);
        typeMap.put(Types.TIMESTAMP, DataType.Date);
        typeMap.put(Types.BINARY, DataType.Integer);
        typeMap.put(Types.VARBINARY, DataType.String);
        typeMap.put(Types.LONGVARBINARY, DataType.String);

        typeMap.put(Types.JAVA_OBJECT, DataType.Object);

        typeMap.put(Types.BLOB, DataType.Blob);
        typeMap.put(Types.CLOB, DataType.Clob);

        typeMap.put(Types.NCHAR, DataType.String);
        typeMap.put(Types.NVARCHAR, DataType.String);
        typeMap.put(Types.LONGNVARCHAR, DataType.String);
        typeMap.put(Types.TIME_WITH_TIMEZONE, DataType.Date);
        typeMap.put(Types.TIMESTAMP_WITH_TIMEZONE, DataType.Date);

        if (typeMap.containsKey(dataType)) {
            return typeMap.get(dataType);
        } else {
            throw new DbException("不支持的数据类型：" + dataType);
        }
    }


    /**
     * 将clob转string
     * 将blob转base64
     */
    protected Object resolveDataValue(Object value) {

        if (value == null) {
            return value;
        }

        if (value instanceof Clob) {
            Clob clob = (Clob) value;
            try {
                return clob.getSubString(1, (int) clob.length());
            } catch (SQLException throwables) {
                //ignore
            }
        } else if (value instanceof Blob) {
            Blob blob = (Blob) value;
            try {
                return Base64.getEncoder().encodeToString(blob.getBytes(0, (int) blob.length()));
            } catch (SQLException throwables) {
                //ignore
            }
        }
        return value;
    }
}
